import { atom } from "jotai";
import { filterPersonAtom } from "./filterPerson";
import { viewModelAtom } from "./viewModel";
import { IEventItem } from "@/lib/types";

const _eventsAtom = atom<IEventItem[]>([]);
const _eventTypesMap = atom<{ [key: string]: number }>({});

export const filteredPersonEvents = atom((get) => {
  const events = get(_eventsAtom);
  const person = get(filterPersonAtom);
  if (!person) {
    return events;
  }
  return events.filter((event) => event.people?.includes(person));
});

export const sortedEventsAtom = atom((get) => {
  const events = get(filteredPersonEvents);
  const viewModel = get(viewModelAtom);
  if (viewModel === "timeline") {
    return events;
  }
  const countMap: { [key: string]: number } = {};
  const orderMap: { [key: string]: number } = {};
  let currOrder = 0;
  events.forEach((event) => {
    if (!countMap[event.type]) {
      countMap[event.type] = 0;
      orderMap[event.type] = currOrder++;
    }
    countMap[event.type]++;
  });

  return events.slice().sort((a, b) => {
    if (a.type === b.type) {
      return 0;
    }
    const d = countMap[b.type] - countMap[a.type];
    if (d !== 0) {
      return d;
    }
    return orderMap[b.type] - orderMap[a.type];
  });
});

export const eventTypesMapAtom = atom((get) => get(_eventTypesMap));
export const eventsAtom = atom(
  (get) => {
    return get(_eventsAtom);
  },
  (get, set, chunks: any[]) => {
    if (!Array.isArray(chunks)) {
      throw new TypeError("Wrong events type");
    }
    const { events, typesMap } = normalizeEvents(chunks);
    set(_eventsAtom, events);
    set(_eventTypesMap, typesMap);
  },
);

function normalizeEvents(_events: any[]) {
  const typesMap: { [key: string]: number } = {};
  const events = _events
    .map((item) => {
      const t = {} as IEventItem;
      for (const key in item) {
        if (/(时间|time)/.test(key) && !t.time) {
          t.time = item[key];
        } else if (/(标题|title)/.test(key) && !t.title) {
          t.title = item[key];
        } else if (/(内容|content)/.test(key) && !t.content) {
          t.content = item[key];
        } else if (
          /(人物|person)/.test(key) &&
          !t.people &&
          isNotEmptyArray(item[key])
        ) {
          t.people = item[key];
        } else if (
          /(地点|place)/.test(key) &&
          !t.place &&
          isNotEmptyArray(item[key])
        ) {
          t.place = item[key];
        } else if (
          /(机构|org)/.test(key) &&
          !t.organization &&
          isNotEmptyArray(item[key])
        ) {
          t.organization = item[key];
        } else if (/(类型|type)/.test(key) && !t.type) {
          t.type = item[key];
          if (!typesMap[t.type]) {
            typesMap[t.type] = 0;
          }
          typesMap[t.type]++;
        }
      }
      return t;
    })
    .filter((item) => {
      const { time, title, content, people, organization, type, place } = item;
      if (!time) {
        return false;
      }
      if (!title && !people && !content && !organization && !type && !place) {
        return false;
      }
      return true;
    })
    .map((item, index) => ({ ...item, id: index + "" }));

  return { events, typesMap };
}

function isNotEmptyArray(item: any) {
  return Array.isArray(item) && item.length > 0;
}

function randomId() {
  if (
    window.crypto &&
    typeof window.crypto === "object" &&
    typeof window.crypto.randomUUID === "function"
  ) {
    return window.crypto.randomUUID();
  }
  return Math.random().toString(16).replace(".", "");
}
